import java.util.*;
import java.util.concurrent.*;

public class PTest implements CallbackInterface
{
	static final int numPTest = 40;

	private static int hund, k, tenK, hunK, mi, max, min, sum;
	private static double ratio;

	private static Vector<Integer> vec;

	private Swarm swarm;

	private Explorer[] exs = new Explorer[numPTest];

	public PTest(Swarm s)
	{
		for (int i = 0; i < numPTest; i ++)
		{
			double[] coe = new double[Explorer.coes],
			     	 dir = new double[Explorer.coes];
	
			exs[i] = new Explorer(coe, dir, this, i);
		}

		this.swarm = s;
	}

	public synchronized void iAmDone(int result, final double[] coe, int ind, int spawn)
	{
		ratio = (double)spawn / result;

		if (result > 1000000) mi ++; else
		if (result > 100000) hunK ++; else
		if (result > 10000) tenK ++; else
		if (result > 1000) k ++; else
		hund ++;

		max = Math.max(max, result);
		min = Math.min(min, result);

		sum += result;
		System.out.println(result + " : " + ratio);
		vec.add(result);
	}

	public void copy(double[] a, double[] b, int tot)
	{
		for (int i = 0; i < tot; i ++)
		{
			a[i] = b[i];
		}
	}

	public void run(int curval, double[] coe)
	{
		hund = k = tenK = hunK = mi = sum = 0;
		max = 0;
		min = 2147483647;

		vec = new Vector<Integer>();

		ExecutorService executor = Executors.newFixedThreadPool(8);

		int iter = numPTest;
		if(curval < 2000000){
			iter = 20;
		}

		for (int i = 0; i < iter; i ++)
		{
			copy(exs[i].getCoe(), coe, Explorer.coes);

			executor.execute(exs[i]);
		}

		executor.shutdown();

		while (!executor.isTerminated()) {}

		System.out.println("Above 1,000,000: " + mi);
		System.out.println("Above 100,000: " + hunK);
		System.out.println("Above 10,000: " + tenK);
		System.out.println("Above 1,000: " + k);
		System.out.println("Above 100: " + hund);
		System.out.println("Max Row Cleared: " + max);
		System.out.println("Min Row Cleared: " + min);
		System.out.println("Average: " + (sum / iter));

		Collections.sort(vec);

		swarm.testDone(vec.get(iter * 3 / 4));
	}

	public static void main(String[] val){
		double[] coe = {36.410178720504824, 39.30232608095497, 121.12548516513772, 3.2666639386589913, 44.27670728219611, 26.386928365072578, -59.447392724301004, 76.70103297569833, 69.8064565712707, 264.62079806632426};
		System.out.println("Coe: " + Swarm.coeToString(coe));
		PTest test = new PTest(null);
		test.run(0, coe);
	}
}
